#ifndef _HOMEWORK_
#define _HOMEWORK_

#include <iostream>

#include <cstdio>
#include <cstdlib>
#include <cstring>

// 默认容量为 10
#define DEFAULT_CAPACITY 10
/*
将数组操作相关数据封装到一个结构体中
    包括数组本身 array_data
    数组对应容量 capacity
    数组存储的有效元素个数 size
*/
struct My_Array
{
    /**
     * array_data 直接当做 int 类型数组使用。
     */
    int *array_data;
    /**
     * 当前 array_data 数组的容量
     */
    int capacity;
    /**
     * 当前 array_data 数组的有效元素个数
     */
    int size;

    /*
    需要在 My_Array 结构体中，实现【增删改查】内容。将之前讲解的
    数组相关算法移植到结构体中，利用结构体成员变量的数据多元性，
    更好完成相关代码实现。
    */
    /**
     * 利用函数对当前结构体中的成员变量进行必要的初始化操作
     * 【核心内容】
     *       1. 数组相关内存空间申请，临时利用 new 关键字
     *       2. 数组容量初始化操作
     *       3. 数组有效元素初始化操作
     */
    void init_my_array();

    /**
     * 添加元素到 My_Array 底层 array_data 数组中，采用的添加
     * 方式为尾插法。
     *
     * @param ele 用户提供的 int 类型元素
     */
    void add_element(int ele);

    /**
     * 找出当前数组中最大值
     *
     * @return int 类型数组中存储的最大值
     */
    int min_value();
    /**..
     * 找出当前数组中的最小值
     *
     * @return int 类型数组中存储的最小值
     */
    int max_value();
    /**
     * 返回整个数组数据的平均值
     *
     * @return double 类型数组中存储的平均值
     */
    double avg_value();

    /**
     * 展示底层数组的数据相关内容
     */
    void show();

    /**
     * 找出指定数据在底层数组中第一次出现的下标位置
     *
     * @param value 目标搜索的数据
     * @return 数据在底层数组中第一次出现的下标位置，如果找到
     *      返回大于等于 0，否则返回 -1
     */
    int find(int value);

    /**
     * 找出指定数据在底层数组中最后一次出现的下标位置
     *
     * @param value 目标搜索的数据
     * @return 数据在底层数组中最后一次出现的下标位置，如果找到
     *      返回大于等于 0，否则返回 -1
     */
    int rfind(int value);

    /**
     * 在当前底层数组中，添加指定元素到目标指定下标
     *
     * @param index 指定添加数据的下标位置。
     * @param ele   指定添加的元素
     */
    void add_element(int index, int ele);

    /**
     * 添加另一个 My_Array 结构体变量数据到当前 My_Array 中
     * 主要是将参数的 My_Array 底层数组内容拷贝到当前 My_Array
     * 底层数组末尾。
     * 
     * @param ma 添加到当前 My_Array 底层数组的结构体 My_Array 变量
     */
    void add_all(My_Array &ma);

    /**
     * 添加另一个 My_Array 结构体变量数据到当前 My_Array 中
     * 主要是将参数的 My_Array 底层数组内容拷贝到当前 My_Array
     * 底层数组指定下标位置 index
     * 
     * @param index 指定添加另一个数组的下标位置
     * @param ma    添加到当前 My_Array 底层数组的结构体 My_Array 变量
     */
    void add_all(int index, My_Array &ma);

    /**
     * 删除当前 My_Array 中指定下标的元素，返回值是被删除的元素数据情况
     * 
     * @param index 指定删除数据的下标位置
     * @return int 对应当前被删除的数据情况
     */
    int remove(int index);

    /**
     * 在当前 My_Array 中删除所有的目标 ele 元素
     * 
     * @param ele 目标删除的元素数据
     */
    void remove_all(int ele);

    /**
     * 在当前 My_Array 中删除和参数 My_Array 的交集
     * 例如:
     *      当前 My_Array 底层数据为 [1, 3, 5, 1, 3, 5, 6]
     *      参数 ma 底层数据为 [3, 5, 2]
     *      调用之后的效果为 [1, 1, 6]
     * 
     * @param ma 删除依据的参数 My_Array 结构体
     */
    void remove_all(My_Array &ma);

    /**
     * 在当前 My_Array 中，删除底层数组中存储的从 begin 开始到 end 下标结束的
     * 所有数据数据内容，要求要头不要尾 [begin, end)
     * 
     * @param begin 删除数据的起始下标位置
     * @param end   删除数据的终止下标位置
     */
    void remove_all(int begin, int end);
    
    /**
     * 在当前 My_Array 中仅保留和参数 My_Array 的交集
     * 例如:
     *      当前 My_Array 底层数据为 [1, 3, 5, 1, 3, 5, 6]
     *      参数 ma 底层数据为 [3, 5, 2]
     *      调用之后的效果为 [3, 5, 3, 5]
     * 
     * @param ma 保留数据依据的参数 My_Array 结构体
     */
    void retain_all(My_Array &ma);

    /**
     * 在当前 My_Array 底层数组中，指定下标位置 index 替换为新元素
     * 
     * @param index     替换指定的下标位置
     * @param new_value 替换使用的新元素
     */
    void replace(int index, int new_value);

    /**
     * 将当前 My_Array 底层数组中所有的 old_value 替换为 new_value
     * 
     * @param old_value 替换目标的老数据
     * @param new_value 替换使用的新数据
     */
    void replace_all(int old_value, int new_value);

    /**
     * 在当前 My_Array 底层数组中，从指定下标为 pos 开始，计数 count 元素
     * 替换为参数 My_Array 对应的数据
     * 例如
     *      当前调用函数 My_Array 底层数据 [1, 2, 3, 4, 5];
     *      参数 My_Array 底层数据 [9, 8, 7]
     *      其他参数实际数据为 pos = 2, count = 2;
     *      执行效果为当前调用函数 My_Array 底层数据
     *          [1, 2, 9, 8, 7, 5];
     * 
     * @param pos   指定替换数据的起始下标位置
     * @param count 替换数据的个数
     * @param ma    替换数据的新数据 My_Array
     */
    void replace_all(int pos, int count, My_Array &ma);

    /**
     * 当前 My_Array 底层数组逆序操作
     */
    void reveser();

    /**
     * 在当前 My_Array 中，找出用户指定下标 index 对应的元素
     * 
     * @param 返回值是目标元素
     */
    int at(int index);

    /**
     * 在当前调用函数的 My_Array 中，从指定下标位置 pos 开始，计数 count 个数
     * 截取得到子 My_Array 结构体
     * 例如
     *      当前调用函数 My_Array 底层数据 [1, 2, 3, 4, 5];
     *      其他参数实际数据为 pos = 2, count = 2;
     *      得到的新 My_Array，底层数据为 [2, 3] 
     * 
     * @param pos   截取子 My_Array 指定的起始下标位置
     * @param count 截取操作对应的元素个数
     * @return 对应当前 My_Array 限制范围以内的子 My_Array 结构体数据
     */
    My_Array &sub_array(int pos, int count);

    /**
     * My_Array 底层数据降序排序，临时排序展示操作，对原数据内容无影响
     */
    void sort_desc();

    /**
     * My_Array 底层数据升序排序，临时排序展示操作，对原数据内容无影响
     */
    void sort_asc();

    /**
     * 销毁当前 My_Array 占用的内存空间
     */
    void destroy();

    void extend(int capacity);
};
#endif